package tools

import config.{Global, MyFile, MyRow}
import models.Tables._
import play.api.libs.json.Json
import utils.TableUtils

object Circos extends MyFile with MyRow {

  def circosPlot(species: String, chrS: String, species2: String, lines: Seq[BlockrangeRow]) = {

    val ref = s"${Global.path}/blockLen/$species.txt".readLines.map(_.split("\t").map(_.trim)).filter(_.head == chrS).zipWithIndex

    val refRow = ref.map { x =>
      val chr = x._1.head
      val length = x._1.last
      Json.obj("id" -> 1, "chr" -> chr, "length" -> length.toInt, "color" -> "red")
    }

    val query = s"${Global.path}/blockLen/$species2.txt".readLines.map(_.split("\t").map(_.trim)).zipWithIndex

    val queryRow = query.map { x =>
      val chr = x._1.head
      val length = x._1.last
      Json.obj("id" -> (x._2 + 2), "chr" -> chr, "length" -> length.toInt, "color" -> "blue")
    }

    val chr1 = query.map(x => x._1.head -> (x._2 + 2)).toMap

    val row = lines.zipWithIndex.map { case (y, i) =>
      if (y.querySpecies == species) {
        Json.obj("bid" -> y.name, "color" -> "black", "id" -> (i + 1),
          "source" -> Json.obj("chr" -> 1, "name" -> chrS, "start" -> y.queryStart, "end" -> y.queryEnd),
          "target" -> Json.obj("chr" -> chr1(y.ref), "name" -> y.ref, "start" -> y.refStart, "end" -> y.refEnd))
      } else {
        Json.obj("bid" -> y.name, "color" -> "black", "id" -> (i + 1),
          "source" -> Json.obj("chr" -> 1, "name" -> chrS, "start" -> y.refStart, "end" -> y.refEnd),
          "target" -> Json.obj("chr" -> chr1(y.query), "name" -> y.query, "start" -> y.queryStart, "end" -> y.queryEnd))
      }
    }
    val collection = queryRow ++ refRow
    val table = lines.map(z => z.getMapByT() ++ Map("qSpecies" -> getTitle(z.querySpecies), "rSpecies" -> getTitle(z.refSpecies)))
    Json.obj("ur" -> row, "collection" -> collection, "table" -> table)
  }

  def circosPlotAll(species: String, species2: String, lines: Seq[BlockrangeRow]) = {

    val ref = s"${Global.path}/blockLen/$species.txt".readLines.map(_.split("\t").map(_.trim)).zipWithIndex

    val refRow = ref.map { x =>
      val chr = x._1.head
      val length = x._1.last
      Json.obj("id" -> (x._2 + 1), "chr" -> chr, "length" -> length.toInt, "color" -> "red")
    }

    val query = s"${Global.path}/blockLen/$species2.txt".readLines.map(_.split("\t").map(_.trim)).zipWithIndex

    val queryRow = query.map { x =>
      val chr = x._1.head
      val length = x._1.last
      Json.obj("id" -> (x._2 + 1 + ref.length), "chr" -> chr, "length" -> length.toInt, "color" -> "blue")
    }

    val chr1 = query.map(x => x._1.head -> (x._2 + 1 + ref.length)).toMap
    val chr2 = ref.map(x => x._1.head -> (x._2 + 1)).toMap

    val row = lines.zipWithIndex.map { case (y, i) =>
      if (y.querySpecies == species) {
        Json.obj("bid" -> y.name, "color" -> "black", "id" -> (i + 1),
          "source" -> Json.obj("chr" -> chr2(y.query), "name" -> y.query, "start" -> y.queryStart, "end" -> y.queryEnd),
          "target" -> Json.obj("chr" -> chr1(y.ref), "name" -> y.ref, "start" -> y.refStart, "end" -> y.refEnd))
      } else {
        Json.obj("bid" -> y.name, "color" -> "black", "id" -> (i + 1),
          "source" -> Json.obj("chr" -> chr2(y.ref), "name" -> y.ref, "start" -> y.refStart, "end" -> y.refEnd),
          "target" -> Json.obj("chr" -> chr1(y.query), "name" -> y.query, "start" -> y.queryStart, "end" -> y.queryEnd))
      }
    }
    val collection = queryRow ++ refRow
    val table = lines.map(z => z.getMapByT() ++ Map("qSpecies" -> getTitle(z.querySpecies), "rSpecies" -> getTitle(z.refSpecies)))
    Json.obj("ur" -> row, "collection" -> collection, "table" -> table)
  }

  def circosPlotAll2(lines: Seq[BlockrangeRow]) = {
    var count = 0
    val color = Map(
      "MSAE" -> "#C23531",
      "MTRU" -> "#61A0A8",
      "XJDY" -> "#2F4554",
      "ZMNO" -> "#D48265"
    )
    val allSpecies = s"${Global.path}/blockLen".listFile.map { x =>
      val name = x.getName.split('.').head
      val index = x.readLines.map(_.split("\t").map(_.trim)).zipWithIndex
      val row = index.map { x =>
        val chr = x._1.head
        val length = x._1.last
        count = count + 1
        (count, name + "-" + chr, length.toInt, color(name))
      }
      (name -> (index, row))
    }
    val chr = allSpecies.flatMap { x =>
      x._2._2.map { y =>
        y._2 -> y._1
      }
    }.toMap
    val row = lines.zipWithIndex.map { case (y, i) =>
      Json.obj("bid" -> y.name, "color" -> "black", "id" -> (i + 1),
        "source" -> Json.obj("chr" -> chr(y.querySpecies + "-" +y.query), "name" -> y.query, "start" -> y.queryStart, "end" -> y.queryEnd),
        "target" -> Json.obj("chr" -> chr(y.refSpecies + "-" + y.ref), "name" -> y.ref, "start" -> y.refStart, "end" -> y.refEnd))
    }

    val collection = allSpecies.flatMap {x=>
      x._2._2.map{y=>
        Json.obj("id" -> y._1, "chr" -> y._2, "length" -> y._3, "color" -> y._4)
      }
    }
    Json.obj("ur" -> row, "collection" -> collection )
  }

  def circosPlotAll3(query: GenomeRow, lines: Seq[GenomeRow] ) = {
    var count = 0
    val color = Map(
      "MSAE" -> "#C23531",
      "MTRU" -> "#61A0A8",
      "XJDY" -> "#2F4554",
      "ZMNO" -> "#D48265"
    )

    val allSpecies =  s"${Global.path}/blockLen".listFile.map { x =>
      val name = x.getName.split('.').head.split('_').head
      val index = x.readLines.map(_.split("\t").map(_.trim)).zipWithIndex
      val row = index.map { x =>
        val chr = x._1.head
        val length = x._1.last
        count = count + 1
        (count, name + "-" + chr, length.toInt, color(name))
      }
      (name -> (index, row))
    }
    val chr = allSpecies.flatMap { x =>
      x._2._2.map { y =>
        y._2 -> y._1
      }
    }.toMap
    val row = lines.zipWithIndex.map { case (y, i) =>
      Json.obj("bid" -> (query.geneid + " - " + y.geneid), "color" -> "black", "id" -> (i + 1),
        "source" -> Json.obj("chr" -> chr(query.species + "-" + query.chr), "name" -> query.chr, "start" -> query.start, "end" -> (query.end + 2000000)),
        "target" -> Json.obj("chr" -> chr(y.species + "-" + y.chr), "name" -> y.chr, "start" -> y.start, "end" -> (y.end + 2000000)))
    }

    val collection = allSpecies.flatMap { x =>
      x._2._2.map { y =>
        Json.obj("id" -> y._1, "chr" -> y._2, "length" -> y._3, "color" -> y._4)
      }
    }
    Json.obj("ur" -> row, "collection" -> collection)
  }


/*
  def circosPlotAll3(query:GenomeRow,lines: Seq[GenomeRow],xjdy:String) = {
    var count = 0
    val color = Map(
      "MSAE" -> "#C23531",
      "MTRU" -> "#61A0A8",
      "XJDY" -> "#2F4554",
      "ZMNO" -> "#D48265"
    )
    val xjdyFile =  s"${Global.path}/blockLen2/XJDY${xjdy}.txt"
    val allSpecies =( s"${Global.path}/blockLen2".listFile.filter(!_.getName.startsWith("XJDY")) :+ xjdyFile.toFile).map { x =>
      val name = x.getName.split('.').head.split('_').head
      val index = x.readLines.map(_.split("\t").map(_.trim)).zipWithIndex
      val row = index.map { x =>
        val chr = x._1.head
        val length = x._1.last
        count = count + 1
        (count, name + "-" + chr, length.toInt, color(name))
      }
      (name -> (index, row))
    }
    val chr = allSpecies.flatMap { x =>
      x._2._2.map { y =>
        y._2 -> y._1
      }
    }.toMap
    val row = lines.zipWithIndex.map { case (y, i) =>
      Json.obj("bid" -> (query.geneid + " - " + y.geneid), "color" -> "black", "id" -> (i + 1),
        "source" -> Json.obj("chr" -> chr(query.species + "-" + query.chr), "name" -> query.chr, "start" -> query.start, "end" -> (query.end+2000000)),
        "target" -> Json.obj("chr" -> chr(y.species + "-" + y.chr), "name" -> y.chr, "start" -> y.start, "end" -> (y.end+2000000)))
    }

    val collection = allSpecies.flatMap { x =>
      x._2._2.map { y =>
        Json.obj("id" -> y._1, "chr" -> y._2, "length" -> y._3, "color" -> y._4)
      }
    }
    Json.obj("ur" -> row, "collection" -> collection)
  }

*/

  def getTitle(species: String): String = {
    TableUtils.genomeName(species)
  }

}
